﻿using System;
using System.Collections;
using System.Net.Mail;
using System.Text;
using System.Web.Profile;
using System.Web.Routing;
using System.Web.Security;
using TeamFranceTriple.Config;
using FranceTriple.Dal;

namespace TeamFranceTriple
{
    public class Global : System.Web.HttpApplication
    {
        // .NET 4.0 Routing : http://msdn.microsoft.com/en-us/library/dd329551.aspx
        private void RegisterRoutes(RouteCollection routes)
        {
            using (RouteTable.Routes.GetWriteLock())
            {
                routes.RouteExistingFiles = false;

                routes.Add(new Route("favicon.ico", new StopRoutingHandler()));
                routes.Add(new Route("robots.txt", new StopRoutingHandler()));
                routes.Add(new Route("{page}.aspx", new StopRoutingHandler()));
                routes.Add(new Route("Services/{service}.asmx", new StopRoutingHandler()));
                routes.Add(new Route("{culture}/{targetPage}/WebResource.axd", new StopRoutingHandler()));
                routes.Add(new Route("{targetPage}/WebResource.axd", new StopRoutingHandler()));
                routes.Add(new Route("{resource}.axd/{*pathInfo}", new StopRoutingHandler()));
                routes.Add(new Route("{resource}.axd", new StopRoutingHandler()));

                routes.MapPageRoute("Activation", "{culture}/{targetPage}/{activationKey}", "~/Account/activation.aspx",
                    true, null, new RouteValueDictionary { { "targetPage", "activation" } });

                routes.MapPageRoute("QuoteMessageDetail", "{culture}/{targetPage}/{messagetype}/{topicid}/{messageid}", "~/Default.aspx",
                    true, null, new RouteValueDictionary { { "targetPage", "messagedetail" }, { "messagetype", "quote" } });

                routes.MapPageRoute("PostMessageDetail", "{culture}/{targetPage}/{messagetype}/{topicid}/{messageid}", "~/Default.aspx",
                    true, null, new RouteValueDictionary { { "targetPage", "messagedetail" }, { "messagetype", "post" } });

                routes.MapPageRoute("MessageDetail", "{culture}/{targetPage}/{messagetype}/{messageid}", "~/Default.aspx",
                    true, null, new RouteValueDictionary { { "targetPage", "messagedetail" } });

                routes.MapPageRoute("TopicByCategoryId", "{culture}/{targetPage}/{viewType}/{categoryId}", "~/Default.aspx",
                    true, null, new RouteValueDictionary { { "targetPage", "topic" }, { "viewType", "bycategory" } });

                routes.MapPageRoute("TopicByTypes", "{culture}/{targetPage}/{viewType}", "~/Default.aspx",
                    true, null, new RouteValueDictionary { { "targetPage", "topic" } });

                routes.MapPageRoute("TopicDetail", "{culture}/{targetPage}/{categoryid}/{topicid}", "~/Default.aspx",
                    true, null, new RouteValueDictionary { { "targetPage", "topicdetail" } });

                routes.MapPageRoute("PostByPostId", "{culture}/{targetPage}/showpost/{postId}", "~/Default.aspx",
                    true, null, new RouteValueDictionary { { "targetPage", "forumpost" } });

                routes.MapPageRoute("PostByTopicId", "{culture}/{targetPage}/{topicId}", "~/Default.aspx",
                    true, null, new RouteValueDictionary { { "targetPage", "forumpost" } });

                routes.MapPageRoute("LaBaff", "{culture}/{targetPage}", "~/labaff.aspx",
                    true, null, new RouteValueDictionary { { "targetPage", "labaff" } });

                routes.MapPageRoute("Default2", "{culture}/{targetPage}", "~/Default2.aspx",
                    true, null, new RouteValueDictionary { { "targetPage", "default2" } });

                routes.MapPageRoute("About", "{culture}/{targetPage}/{activeviewindex}", "~/Default.aspx",
    true, null, new RouteValueDictionary { { "targetPage", "about" } });

                routes.MapPageRoute("DefaultWithCulture", "{culture}/{targetPage}", "~/Default.aspx");

                routes.MapPageRoute("Home", "{culture}", "~/Default.aspx");
            }

            //routes.MapPageRoute("",
            //    "SalesReport/{locale}/{year}/{*queryvalues}", "~/sales.aspx");

            //routes.MapPageRoute("SalesSummaryRoute",
            //    "SalesReportSummary/{locale}", "~/sales.aspx");

            //routes.MapPageRoute("SalesDetailRoute",
            //    "SalesReportDetail/{locale}/{year}/{*queryvalues}", "~/sales.aspx",
            //    false);

            //routes.MapPageRoute("SalesCurrentYearRoute",
            //    "SalesReportCurrent/{locale}/{year}/{*queryvalues}", "~/sales.aspx",
            //    false,
            //    new RouteValueDictionary { { "locale", "US" }, { "year", DateTime.Now.Year.ToString() } });

            //routes.MapPageRoute("ExpenseCurrentYearRoute",
            //    "ExpenseReportCurrent/{locale}", "~/expenses.aspx",
            //    false,
            //    new RouteValueDictionary { { "locale", "US" }, { "year", DateTime.Now.Year.ToString() } },
            //    new RouteValueDictionary { { "locale", "[a-z]{2}" }, { "year", @"\d{4}" } });

            //routes.MapPageRoute("ExpenseDetailRoute",
            //    "ExpenseReportDetail/{locale}/{year}/{*queryvalues}", "~/expenses.aspx",
            //    false,
            //    new RouteValueDictionary { { "locale", "US" }, { "year", DateTime.Now.Year.ToString() } },
            //    new RouteValueDictionary { { "locale", "[a-z]{2}" }, { "year", @"\d{4}" } },
            //    new RouteValueDictionary { { "account", "1234" }, { "subaccount", "5678" } });


            // Automaticaly generate link
            //
            //<asp:HyperLink ID="HyperLink1" runat="server" 
            //    NavigateUrl="~/salesreportsummary/2010/">
            //    Sales Report - All locales, 2010
            //</asp:HyperLink>
            //<br />
            //<asp:HyperLink ID="HyperLink2" runat="server" 
            //    NavigateUrl="~/salesreport/WA/2011/">
            //    Sales Report - WA, 2011
            //</asp:HyperLink>
            //<br />
            //<asp:HyperLink ID="HyperLink3" runat="server" 
            //    NavigateUrl="~/expensereport/">
            //    Expense Report - Default Locale and Year (US, current year)
            //</asp:HyperLink>
            //<br />

            //Access Url Parameter
            //
            //<h1>
            //    Expense Report for
            //    <asp:Literal ID="Literal1" 
            //    Text="<%$RouteValue:locale%>" 
            //    runat="server"></asp:Literal>,
            //    <asp:Literal ID="Literal2" 
            //    Text="<%$RouteValue:year%>" 
            //    runat="server"></asp:Literal>
            //</h1>

            //        LocaleLiteral.Text = Page.RouteData.Values["locale"] == null ?
            //"All locales" : Page.RouteData.Values["locale"].ToString();

            // Create route
            //
            //        RouteValueDictionary parameters =
            //new RouteValueDictionary  
            //    { 
            //        {"locale", "CA" }, 
            //        { "year", "2008" } , 
            //        { "category", "recreation" }
            //    };

            //        VirtualPathData vpd =
            //            RouteTable.Routes.GetVirtualPath(null, "ExpensesRoute", parameters);

            //        HyperLink6.NavigateUrl = vpd.VirtualPath;

        }

        /// <summary>
        /// Plus besoin de livrer un nouveau lorsque il est créé
        /// </summary>
        private void CreateDefaultRoles()
        {
            //
            // Roles.MaxCachedResults, défini dans le Web.Config, est à mettre à jour en fonction du nombre de role créé ici
            //

            if (!Roles.RoleExists("Fans"))
                Roles.CreateRole("Fans");

            if (!Roles.RoleExists("FriendlyTeamMember"))
                Roles.CreateRole("FriendlyTeamMember");

            if (!Roles.RoleExists("FriendlyTeamGuildMaster"))
                Roles.CreateRole("FriendlyTeamGuildMaster");

            if (!Roles.RoleExists("Member"))
                Roles.CreateRole("Member");

            if (!Roles.RoleExists("Public"))
                Roles.CreateRole("Public");

            if (!Roles.RoleExists("RoleAdminBF"))
                Roles.CreateRole("RoleAdminBF");

            if (!Roles.RoleExists("RoleAdminForum"))
                Roles.CreateRole("RoleAdminForum");

            if (!Roles.RoleExists("RoleAdminTS"))
                Roles.CreateRole("RoleAdminTS");

            if (!Roles.RoleExists("RoleAdminWebApp"))
                Roles.CreateRole("RoleAdminWebApp");

            if (!Roles.RoleExists("RoleDevWebApp"))
                Roles.CreateRole("RoleDevWebApp");

            if (!Roles.RoleExists("RoleEveningChief"))
                Roles.CreateRole("RoleEveningChief");

            if (!Roles.RoleExists("RoleHR"))
                Roles.CreateRole("RoleHR");

            if (!Roles.RoleExists("RoleUniqueFinancial"))
                Roles.CreateRole("RoleUniqueFinancial");
        }

        void Application_Start(object sender, EventArgs e)
        {
            // Code that runs on application startup
            RegisterRoutes(RouteTable.Routes);
            CreateDefaultRoles();
        }

        void Application_End(object sender, EventArgs e)
        {
            //  Code that runs on application shutdown

        }

        void Application_BeginRequest(object sender, EventArgs e)
        {
            //  Code that runs on request begin

        }

        void Session_Start(object sender, EventArgs e)
        {
            // Code that runs when a new session is started
            if (!User.Identity.IsAuthenticated)
            {
                Session["AnonymousID"] = Request.AnonymousID;
                if (!Roles.IsUserInRole(Request.AnonymousID, "Public"))
                    Roles.AddUserToRole(Request.AnonymousID, "Public");
            }
        }

        void Session_End(object sender, EventArgs e)
        {
            // Code that runs when a session ends. 
            // Note: The Session_End event is raised only when the sessionstate mode
            // is set to InProc in the Web.config file. If session mode is set to StateServer 
            // or SQLServer, the event is not raised.
            if (Session["AnonymousID"] != null)
            {
                if (Roles.IsUserInRole(Session["AnonymousID"].ToString(), "Public"))
                    Roles.RemoveUserFromRole(Session["AnonymousID"].ToString(), "Public");

                ////////
                // Delete the anonymous profile. If the anonymous ID is not 
                // needed in the rest of the site, remove the anonymous cookie.

                ProfileManager.DeleteProfile(Session["AnonymousID"].ToString());
                AnonymousIdentificationModule.ClearAnonymousIdentifier();

                //// Delete the user row that was created for the anonymous user.
                Membership.DeleteUser(Session["AnonymousID"].ToString(), true);

                Session["AnonymousID"] = null;
            }
        }

        void Profile_MigrateAnonymous(Object sender, ProfileMigrateEventArgs e)
        {
            UserProfile anonymousProfile = UserProfile.GetUserProfile(e.AnonymousID);
            UserProfile Profile = UserProfile.GetUserProfile();
            if (anonymousProfile.UserChoosenCulture != String.Empty)
            {
                Profile.UserChoosenCulture = anonymousProfile.UserChoosenCulture;
            }

            if (anonymousProfile.UserTheme != String.Empty)
            {
                Profile.UserTheme = anonymousProfile.UserTheme;
            }

            ////////
            // Delete the anonymous profile. If the anonymous ID is not 
            // needed in the rest of the site, remove the anonymous cookie.

            ProfileManager.DeleteProfile(e.AnonymousID);
            AnonymousIdentificationModule.ClearAnonymousIdentifier();

            //// Delete the user row that was created for the anonymous user.
            Membership.DeleteUser(e.AnonymousID, true);

            //Todo: la mise à jour de la dernière adresse ip ne se fait par la fenetre de connexion : compléter cette mise à jour
            String AdressIp;
            //Retrouver l'adresse d'origine, même si le visiteur est derriere un proxy
            AdressIp = Request.ServerVariables["REMOTE_HOST"].ToString();
            if (Context.Request.ServerVariables["HTTP_X_FORWARDED_FOR"] != null)
                AdressIp = Context.Request.ServerVariables["HTTP_X_FORWARDED_FOR"];
            if (AdressIp == "::1")
                AdressIp = "127.0.0.1";
            UserProfile.GetUserProfile().LastAddressIp = AdressIp;

            // Forcer la mise à jour des informations sur le requeteur.
            Session["Requester"] = null;
        }

        void Application_Error(object sender, EventArgs e)
        {
            // Code that runs when an unhandled error occurs            
            Exception exc = this.Server.GetLastError();
            if (exc != null)
            {
                String MailBody = ExceptionToMessage(exc);

                if (exc.InnerException != null)
                    Session["lasterror"] = exc.InnerException.Message;

                if (TeamFranceTripleConfig.WebConfig.mailerror.enable)
                    MailManager.SendEmail(
            new MailAddress(TeamFranceTripleConfig.WebConfig.mailerror.from.ToString()),
            new MailAddress(TeamFranceTripleConfig.WebConfig.mailerror.to.ToString()),
            "Web Application TeamFranceTriple Error : " + exc.Message.ToString(),
            MailBody, false);
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="ex"></param>
        /// <returns></returns>
        private string ExceptionToMessage(Exception ex)
        {
            //Todo: Ajouter les paramètres du routing
            StringBuilder strbMsg;

            strbMsg = new StringBuilder(4000);

            strbMsg.AppendLine("<html><head></head><body><table border=\"1\">");

            //FRO: plutôt que d'analyser uniquement la première exception, analysons-les toutes.
            //ex.GetBaseException
            do
            {
                strbMsg.AppendLine("<tr><td>Message</td><td>" + ex.Message + "</td></tr>");

                strbMsg.AppendLine("<tr><td>Message</td><td>" + ex.Message + "</td></tr>");
                strbMsg.AppendLine("<tr><td>Source</td><td>" + ex.Source + "</td></tr>");
                strbMsg.AppendLine("<tr><td>Type</td><td>" + ex.GetType().ToString() + "</td></tr>");
                if (ex.TargetSite != null)
                    strbMsg.AppendLine("<tr><td>TargetSite</td><td>" + ex.TargetSite.ToString() + "</td></tr>");
                if (ex.Data.Count > 0)
                {
                    strbMsg.AppendLine("<tr><td colspan=2>Additional data</td></tr>");
                    foreach (DictionaryEntry de in ex.Data)
                        strbMsg.AppendLine("<tr><td>" + de.Key + "</td><td>" + de.Value + "</td></tr>");
                }
                if (ex.HelpLink != null)
                    strbMsg.AppendLine("<tr><td>HelpLink</td><td><a href=\"" + ex.HelpLink + "\">" + ex.HelpLink + "</a></td></tr>");
                if (ex.StackTrace != null)
                    strbMsg.AppendLine("<tr><td>StackTrace</td><td>" + ex.StackTrace + "</td></tr>");
                strbMsg.AppendLine("<tr><td colspan=2>&nbsp;</td></tr>");
                if (ex.InnerException != null)
                    ex = ex.InnerException;
                else
                    break;
            } while (true);

            //FRO : le vieil article : http://www.aspfr.com/codes/GESTION-ERREUR-STANDARD_9043.aspx

            strbMsg.AppendLine("<tr><td colspan=2>ServerVariables</td></tr>");
            foreach (string variable in this.Context.Request.ServerVariables)
            {
                strbMsg.AppendLine("<tr><td>" + variable + "</td><td>" + this.Context.Request.ServerVariables[variable] + "</td></tr>");
            }

            strbMsg.AppendLine("<tr><td colspan=2>&nbsp;</td></tr>");
            strbMsg.AppendLine("<tr><td colspan=2>Capabilities</td></tr>");
            foreach (DictionaryEntry variable in this.Context.Request.Browser.Capabilities)
            {
                strbMsg.AppendLine("<tr><td>" + variable.Key + "</td><td>" + variable.Value + "</td></tr>");
            }

            strbMsg.AppendLine("<tr><td colspan=2>&nbsp;</td></tr>");
            strbMsg.AppendLine("<tr><td colspan=2>Cookies</td></tr>");
            foreach (string variable in this.Context.Request.Cookies)
            {
                strbMsg.AppendLine("<tr><td>" + variable + "</td><td>" + this.Context.Request.Cookies[variable] + "</td></tr>");
            }

            strbMsg.AppendLine("</table></body></html>");

            return strbMsg.ToString();
        }
    }
}
